package com.guanjialhx.controller;


import com.alibaba.fastjson.JSON;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.guanjialhx.pojo.Apply2;
import com.guanjialhx.pojo.PayVo;
import com.guanjialhx.pojo.QRCodeVo;
import com.guanjialhx.pojo.Result;
import com.guanjialhx.utils.CodeMsg;
import com.guanjialhx.utils.PhoneCode;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author 邓昕劼
 * @version 1.3
 * 管家系统公众号，我的二维码h5获取openid并跳到web页面
 */
@RestController
@CrossOrigin
@RequestMapping(value = "/QRCode")
public class QRCodeController {
    //日志打印
    private final Logger log = LoggerFactory.getLogger(QRCodeController.class);

    @Value("${WxJavaUrl}")
    private String WxJavaUrl;

    //管家微信公众号 参数
    private static final String appIdWX = "wxcb64d81519996b30";
    private static final String appSecretWx = "0bd137a776a560c9562692626d559a51";

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    /**
     * 访问启效云的参数
     */
    private static final String appKey = "d3aa45bbd1e94d70b5fe59b1fa37da21";
    private static final String appSecret = "883fbc209be344e899544af7c7caa0fc";
    private static final String qxUrl = "https://changhu.qixiaocloud.com";

    /**
     * 管家公众号我的明细   菜单点击 获取code 并重定向
     *
     * @param request
     * @param resp
     */
    @RequestMapping(value = "/redirect_mine", method = RequestMethod.GET)
    public void redirect_mine(HttpServletRequest request, HttpServletResponse resp) {
        String refereesOpenid = request.getParameter("refereesOpenid");
        // 用户扫码进入 把推荐人Openid存到session中
        request.getSession().setAttribute("refereesOpenid", refereesOpenid);
        /**
         * 网页授权获取用户基本信息：两种 scope 域
         * snsapi_base 不需要用户点同意，直接跳转到授权后的页面，只能用于获取openid，不能获取用户基本信息
         *
         * snsapi_userinfo 会征求用户同意，授权后，可以获取用户基本信息
         */
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxcb64d81519996b30&redirect_uri=" +
                WxJavaUrl +
                "/QRCode/oauth_mine?response_type=code&scope=snsapi_userinfo&state=1&connect_redirect=1#wechat_redirect";
        try {
            resp.sendRedirect(url);
        } catch (Exception e) {
            e.printStackTrace();
//            logger.info("LoginController/redirect失败");
        }
    }

    /**
     * 获取登录用户基本信息
     *
     * @param request
     * @param resp
     */
    @RequestMapping(value = "/oauth_mine", method = RequestMethod.GET)
    public void weChatOauth_mine(HttpServletRequest request, HttpServletResponse resp) {
        try {
            //得到code
            String code = request.getParameter("code");
            String appId = "wxcb64d81519996b30";
            String appSecret = "0bd137a776a560c9562692626d559a51";
            /**
             * 使用code换取access_token
             * 参数说明
             * appid=APPID（公众号唯一标识）
             * secret=SECRET（公众号的appsecret）
             * code=CODE（第一步获取的code参数）
             * grant_type=authorization_code（无需更改）
             *
             * 结果解释
             * access_token	网页授权接口调用凭证,注意：此access_token与基础支持的access_token不同
             * expires_in	access_token接口调用凭证超时时间，单位（秒）
             * refresh_token	用户刷新access_token
             * openid	用户唯一标识，请注意，在未关注公众号时，用户访问公众号的网页，也会产生一个用户和公众号唯一的OpenID
             * scope	用户授权的作用域，使用逗号（,）分隔
             */
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code";
            String access_tokenJson = httpGetJson(url);
            // String类型转Json对象并获取指定数据
            JsonObject jsonObject = new JsonParser().parse(access_tokenJson).getAsJsonObject();
            //通过getAsJsonArray获取：对应的[]里面的数据
            String access_token = jsonObject.getAsJsonObject().get("access_token")
                    .getAsString();
            String openid = jsonObject.getAsJsonObject().get("openid")
                    .getAsString();

            /**
             * 使用access_token获取用户信息
             * 参数说明
             * access_token=ACCESS_TOKEN（第2步获取的access_token参数，此access_token与基础支持的access_token不同）
             * openid=OPENID（第2步获取的openid参数）
             * langlang=zh_CN	返回国家地区语言版本，zh_CN 简体，zh_TW 繁体，en 英语
             *
             * 结果解释
             * openid	用户的唯一标识
             * nickname	用户昵称
             * sex	用户的性别，值为1时是男性，值为2时是女性，值为0时是未知
             * province	用户个人资料填写的省份
             * city	普通用户个人资料填写的城市
             * country	国家，如中国为CN
             * headimgurl	用户头像，最后一个数值代表正方形头像大小（有0、46、64、96、132数值可选，0代表640*640正方形头像），用户没有头像时该项为空
             * privilege	用户特权信息，json 数组，如微信沃卡用户为（chinaunicom）
             */
            String urlTwo = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid + "&lang=zh_CN";
            // 用户的唯一标识存到session中   如果该用户推荐 就生成二维码
            request.getSession().setAttribute("openid", openid);
            String userinfoJson = httpGetJson(urlTwo);
            if (!userinfoJson.contains("errcode")) {
                // String类型转Json对象并获取指定数据
                JsonObject userinfoJsonObject = new JsonParser().parse(userinfoJson).getAsJsonObject();
                //通过getAsJsonArray获取：对应的[]里面的数据
                String nickname = userinfoJsonObject.getAsJsonObject().get("nickname").getAsString();
                String sex = userinfoJsonObject.getAsJsonObject().get("sex").getAsString();
               log.info("用户基本信息 ： code=" + code + "---access_token=" + access_token + "---openid=" + openid + "---nickname=" + nickname + "---sex" + sex);
                try {
                    String qxToken  = this.token();
                    Map<String, String> headMap = new HashMap<>();
                    Map param = new HashMap();
                    String url2 = "https://changhu.qixiaocloud.com/open/qx-apaas-lowcode/gj/SelectOpenId";
                    headMap.put("Authorization", qxToken);
                    param.put("openid", openid);
                    String qxAdd = QiXiaoDataController.postJsonParam(url2, param, headMap);
                    log.info("我的二维码："+qxAdd);
                    net.sf.json.JSONObject qxAddJJson = net.sf.json.JSONObject.fromObject(qxAdd);
                    net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(qxAddJJson.getString("data"));
                    String codeS = data.getString("code");
                    String phoneS = "";
                    if (data.has("phone")) {
                        phoneS = data.getString("phone");
                    }
                    if (codeS.equals("有")) {
                        log.info("有");
                        resp.sendRedirect("http://gjweb.lihexinzhiye.com/code?openid=" + openid + "&phone=" + phoneS);
                    }
                    if (codeS.equals("没有")) {
                        log.info("没有");
                        resp.sendRedirect("http://gjweb.lihexinzhiye.com/code?openid=" + openid);
                    }
                    System.out.println("openid=" + openid);
                } catch (IOException e) {
                    e.printStackTrace();
                    log.info("LoginController/weChatOauth 重定向公众号首页失败");
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //微信支付成功页面的参数获取
    @GetMapping("selectPaySuc")
    public Result selectPaySuc(String name, String IDcard, String phone) {
        try {
            String qxToken = this.token();
            Map<String, String> headMap = new HashMap<>();
            Map param = new HashMap();
            String url = "https://changhu.qixiaocloud.com/open/qx-apaas-lowcode/gj/SelectPaySuc";
            headMap.put("Authorization", qxToken);
            param.put("name", name);
            param.put("IDcard", IDcard);
            String qxAdd = QiXiaoDataController.postJsonParam(url, param, headMap);
            log.info("qxAdd:" + qxAdd);
            net.sf.json.JSONObject qxAddJJson = net.sf.json.JSONObject.fromObject(qxAdd);
            net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(qxAddJJson.getString("data"));
            String money = data.getString("money");
            String shddh = data.getString("shddh");
            String zfdh = data.getString("zfdh");
            String zfTime = data.getString("zfTime");
            String ckName = "";
            String ckPhone = "";
            if (data.has("ckName")) {
                ckName = data.getString("ckName");
                log.info("ckName = " + ckName);
            }
            if (data.has("ckPhone")) {
                ckPhone = data.getString("ckPhone");
                log.info("ckPhone = " + ckPhone);
            }
            log.info("name = " + name);
            log.info("IDcard = " + IDcard);
            log.info("phone = " + phone);
            log.info("zfTime = " + zfTime);
            log.info("money = " + money);
            log.info("shddh = " + shddh);
            log.info("zfdh = " + zfdh);
            PayVo payVo = new PayVo();
            payVo.setMoney(money);
            payVo.setShddh(shddh);
            payVo.setZfdh(zfdh);
            payVo.setZfTime(zfTime);
            if (data.has("ckName")) {
                payVo.setCkName(ckName);
            }
            if (data.has("ckPhone")) {
                payVo.setCkPhone(ckPhone);
            }
            payVo.setName(name);
            payVo.setPhone(phone);
            payVo.setIDcard(IDcard);
            return Result.success(payVo);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error(e.toString());
        }

    }

    //根据老师的手机号码和openid查询老师的数据
    @GetMapping("SelectDetail")
    public Result WxPay(String openid, String phone, HttpServletRequest request, HttpServletResponse resp) {
        try {
            String qxToken  = this.token();
            Map<String, String> headMap = new HashMap<>();
            Map param = new HashMap();
            String url = "https://changhu.qixiaocloud.com/open/qx-apaas-lowcode/gj/SelectDetail";
            headMap.put("Authorization", qxToken);
            param.put("openid", openid);
            param.put("phone", phone);
            String qxAdd = QiXiaoDataController.postJsonParam(url, param, headMap);
            log.info("查询报名二维码 = " + qxAdd);
            net.sf.json.JSONObject qxAddJJson = net.sf.json.JSONObject.fromObject(qxAdd);
            net.sf.json.JSONObject data = net.sf.json.JSONObject.fromObject(qxAddJJson.getString("data"));
            if (data.isEmpty() || data.getString("name").equals("无绑定数据")) {
                return Result.error("666");
            } else {
                log.info("Qcdata = " + data);
                String id = data.getString("ckid");
                String name = data.getString("name");
                name = this.encryptBASE64(name);
                name = name.replace("+", "%2B");
                String phone1 = data.getString("phone");
                log.info("openid = " + openid);
                log.info("name = " + name);
                log.info("phone1 = " + phone1);
                log.info("id = " + id);
                QRCodeVo qrCodeVo = new QRCodeVo();
                qrCodeVo.setId(id);
                qrCodeVo.setName(name);
                qrCodeVo.setOpenid(openid);
                qrCodeVo.setPhone1(phone1);
                return Result.success(qrCodeVo);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("666");
        }

    }


    /**工具-------------------------------------------------------------------------------------------------------------------------------------------------------**/


    /**
     * 获取短信验证码
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/getDesignatedVerificationCode", method = RequestMethod.GET)
    @ResponseBody
    public Result getDesignatedVerificationCode(HttpServletRequest request) {
        try {
            String mobile = request.getParameter("mobile");
            String openid = request.getParameter("openid");
            System.out.println("mobile = " + mobile);
            System.out.println("openid = " + openid);
            if (mobile != null) {
                return PhoneCode.getPhonemsg(mobile, openid);
            } else {
                return Result.error(String.valueOf(CodeMsg.wrongLoginPhoneNumber));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error(String.valueOf(CodeMsg.SERVER_EXCEPTION));
        }

    }

    /**
     * 加密
     *
     * @param str
     * @return
     * @throws Exception
     */
    public static String encryptBASE64(String str) throws Exception {
        return (new BASE64Encoder()).encodeBuffer(str.getBytes());
    }

    private Apply2 fetchData(Apply2 apply2) {
        try {
            String url2 = "https://changhu.qixiaocloud.com/open/qx-apaas-lowcode/gj/SelectApplyByID";
            //判断是否在有效时间里面
            Map<String, String> headMap2 = new HashMap<>();
            Map param2 = new HashMap();
            String qxToken = this.token();
            headMap2.put("Authorization", qxToken);
            param2.put("id", apply2.getId());
            String qxAdd2 = LoginController.postJsonParam(url2, param2, headMap2);
            net.sf.json.JSONObject qxAddJJson2 = net.sf.json.JSONObject.fromObject(qxAdd2);
            net.sf.json.JSONObject data2 = net.sf.json.JSONObject.fromObject(qxAddJJson2.getString("data"));
            Apply2 apply21 = new Apply2();
            setUserProperties(apply21, data2);
            return apply21;
        } catch (Exception e) {
            return null;
        }
    }

    public void setUserProperties(Apply2 apply2, net.sf.json.JSONObject data2) {
        apply2.setName(getValue(data2, "name"));
        apply2.setMoney(getValue(data2, "money"));
        apply2.setPhone(getValue(data2, "phone"));
    }


    private String getValue(net.sf.json.JSONObject data, String key) {
        return data.has(key) ? data.getString(key) : null;
    }


    /**
     * 访问http接口得到返回数据 https://wx.changhuyun.com/api/login/jscode2session?appid=""&
     * -暂时停用
     *
     * @param url
     * @return
     */
    public static String httpGetJson(String url) {
        String result = "";
        BufferedReader in = null;
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            //connection.setRequestProperty("contentType", "utf8");
            connection.setReadTimeout(5000);
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            // Map<String, List<String>> map = connection.getHeaderFields();


            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream(), "UTF-8"));//防止乱码
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
            result = "";
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }

        return result;
    }

    /**
     * 生成访问启效云的token
     */
    public String token() {
        try {
            String url = qxUrl + "/open/oauth/token";
            Map<String, String> headMap = new HashMap<>();
            Map param = new HashMap();
            param.put("appKey", appKey);
            param.put("appSecret", appSecret);
            String qxLogin = null;
            qxLogin = WeChatPayInfoController.postJsonParam(url, param, headMap);
            log.info("qxLogin = " + qxLogin);
            net.sf.json.JSONObject qxLoginJson = net.sf.json.JSONObject.fromObject(qxLogin);
            String success = qxLoginJson.getString("success");
            if ("true".equals(success)) {
                net.sf.json.JSONObject qxData = net.sf.json.JSONObject.fromObject(qxLoginJson.getString("data"));
                String qxToken = qxData.getString("access_token");
                //将token存到redis设置全局有效时间 10分钟
                log.info("qxToken = " + qxToken);
                return qxToken;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将map数据转成json数据
     */
    public static String postJsonParam(String url, Map<String, String> param, Map<String, String> headMap) throws Exception {
        String jsonparam = mapToJSON(param);
        return doPost(url, jsonparam, headMap);
    }

    /**
     * map 转 json
     *
     * @param param
     * @return
     */
    public static String mapToJSON(Map param) {
        String json = JSON.toJSONString(param);
        return json;
    }

    /**
     * post请求（用于请求json格式的参数）
     *
     * @param url
     * @param params
     * @param headMap
     * @return
     */
    public static String doPost(String url, String params, Map<String, String> headMap) throws Exception {

        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);// 创建httpPost
        httpPost.setHeader("Accept", "application/json");
        httpPost.setHeader("Content-Type", "application/json");
        //如果headMap不为空，则需要添加接口鉴权字段
        if (headMap != null) {
            Iterator it = headMap.keySet().iterator();
            while (it.hasNext()) {
                String key = it.next().toString();
                httpPost.setHeader(key, headMap.get(key));
            }
        }
        String charSet = "UTF-8";
        StringEntity entity = new StringEntity(params, charSet);
        httpPost.setEntity(entity);
        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httpPost);
            StatusLine status = response.getStatusLine();
            int state = status.getStatusCode();
            if (state == HttpStatus.SC_OK) {
                HttpEntity responseEntity = response.getEntity();
                String jsonString = EntityUtils.toString(responseEntity, "UTF-8");
                return jsonString;
            } else {
                System.out.println("!!!!!!!!responseEntity:" + EntityUtils.toString(response.getEntity(), "UTF-8"));
                return "请求失败，服务器状态码：" + state;
            }
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
